using Gateway.Common.Models;
using Gateway.Domain.Entities;
using Gateway.IApplication.BaseInput;
using Gateway.IApplication.Role;
using Gateway.IApplication.Role.Input;
using Gateway.IRepositories;
using Microsoft.EntityFrameworkCore;

namespace Gateway.Application;
/// <summary>
/// 
/// </summary>
public class RoleApp : IRoleApp
{
    private readonly IAppRepository<Role> _repository;
    private readonly IUnitOfWork _unitOfWork;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="repository"></param>
    /// <param name="unitOfWork"></param>
    public RoleApp(IAppRepository<Role> repository, IUnitOfWork unitOfWork)
    {
        _repository = repository;
        _unitOfWork = unitOfWork;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<string> Add(CreateRoleInput input)
    {
        var entity = new Role(roleName: input.RoleName, roleAlias: input.RoleAlias, remark: input.Remark,
            seqNo: input.SeqNo);
        input.Disabled = input.Disabled ?? "N";
        entity.SetDisabled(input.Disabled);
        await _repository.AddAsync(entity);
        await _unitOfWork.CommitAsync();
        return entity.Id;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> Update(UpdateRoleInput input)
    {
        var entity = await _repository.GetAsync(input.RoleId);
        if (entity == null)
            throw new MyException("数据无效");
        entity.Update(roleName: input.RoleName, roleAlias: input.RoleAlias, remark: input.Remark,
            seqNo: input.SeqNo);
        input.Disabled = input.Disabled ?? "N";
        entity.SetDisabled(input.Disabled);
        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> Remove(string id)
    {
        var entity = await _repository.FirstOrDefaultAsync(p => p.Id.Equals(id));
        if (entity == null)
            throw new MyException("数据无效");
        entity.SetDeleted();
        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> Disable(DisableInput input)
    {
        var entity = await _repository.FirstOrDefaultAsync(p => p.Id.Equals(input.Id));
        if (entity == null)
            throw new MyException("数据无效");
        entity.SetDisabled(input.Disable ?? "N");
        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> SetMenusAndPermission(SetMenusAndPermissionInput input)
    {
        var entity = await _repository.Entities.Include(c=>c.RoleMenus)
            .Include(c=>c.RoleExtensionPermissions)
            .FirstOrDefaultAsync(p => p.Id.Equals(input.RoleId));
        if (entity == null)
            throw new MyException(SystemErrorCode.DataIsNotAvailable);
        if (input.Menus?.Count > 0)
        {
            entity.SetMenus(input.Menus.Select(p => p.MenuId).ToList());
        }

        if (input.Permissions?.Count > 0)
        {
            entity.SetPermission(input.Permissions.Select(p =>
                    new RoleExtensionPermission(authType: p.AuthType, authKey: p.AuthKey, authValue: p.AuthValue))
                .ToList());
        }

        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
}